﻿using JTLeigh.Commerce.Spencer.Core.Common;
using JTLeigh.Commerce.Spencer.Features.ProductFeedback.Common;
using JTLeigh.Commerce.Spencer.Features.ProductFeedback.Service.Contracts;
using JTLeigh.Commerce.Spencer.Features.ProductFeedback.Service.Contracts.Runtime.GetProductFeedback;
using JTLeigh.Commerce.Spencer.Features.ProductFeedback.Service.Contracts.Runtime.GetProductFeedbackSnapshot;
using JTLeigh.Commerce.Spencer.Features.ProductFeedback.Service.Contracts.Runtime.GetProductFeedbackSummaries;
using JTLeigh.Commerce.Spencer.Features.ProductFeedback.Service.Commands.Runtime;
using JTLeigh.Commerce.Spencer.Core.Service;
using Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.WCF;
using Microsoft.Practices.Unity;

namespace JTLeigh.Commerce.Spencer.Features.ProductFeedback.Service
{

	/// <summary>
	/// WCF service implementation for the Product Feedback Runtime service.
	/// </summary>
	[ExceptionShielding(ProductFeedbackExceptionPolicy.Service)]
    [DependencyInjectionServiceBehavior]
	public class ProductFeedbackRuntimeService : IProductFeedbackRuntimeService
	{

		#region Properties

		/// <summary>
		/// Gets or sets the dependency injection container to use to resolve dependencies.
		/// </summary>
		/// <remarks>
		/// <para>
		/// Services that have multiple commands with multiple dependencies should depend on 
		/// <see cref="IUnityContainer"/> and use the container to resolve commands on-demand.
		/// </para>
		/// </remarks>
		[Dependency]
		public IUnityContainer Container { get; set; }

		#endregion // Properties

		#region IProductFeedbackRuntimeService Members

		/// <summary>
		/// Gets all feedback for a single product, including all ratings, recommendations, 
		/// reviews, and relevant attribute metadata.
		/// </summary>
		/// <param name="request">The <see cref="GetProductFeedbackRequest"/> request object.</param>
		/// <returns>The <see cref="GetProductFeedbackResponse"/> response object.</returns>
		public GetProductFeedbackResponse GetProductFeedback(GetProductFeedbackRequest request)
		{
			GetProductFeedbackCommand command;

			Safety.AssertArgumentNotNull("request", request);

			command = Container.Resolve<GetProductFeedbackCommand>();
			return command.GetProductFeedback(request);
		}

		/// <summary>
		/// Gets a snapshot of the feedback for a single product, including total and average 
		/// ratings, rating breakdowns, total and positive recommendations, total reviews, and
		/// relevant attribute metadata.
		/// </summary>
		/// <param name="request">The <see cref="GetProductFeedbackSnapshotRequest"/> request 
		/// object.</param>
		/// <returns>The <see cref="GetProductFeedbackSnapshotResponse"/> response object.</returns>
		public GetProductFeedbackSnapshotResponse GetProductFeedbackSnapshot(GetProductFeedbackSnapshotRequest request)
		{
			GetProductFeedbackSnapshotCommand command;

			Safety.AssertArgumentNotNull("request", request);

			command = Container.Resolve<GetProductFeedbackSnapshotCommand>();
			return command.GetProductFeedbackSnapshot(request);
		}

		/// <summary>
		/// Gets summaries of the feedback for multiple products, including total and average
		/// ratings, total and positive recommendations, and total reviews.
		/// </summary>
		/// <param name="request">The <see cref="GetProductFeedbackSummariesRequest"/> request
		/// object.</param>
		/// <returns>The <see cref="GetProductFeedbackSummariesResponse"/> response object.</returns>
		public GetProductFeedbackSummariesResponse GetProductFeedbackSummaries(GetProductFeedbackSummariesRequest request)
		{
			GetProductFeedbackSummariesCommand command;

			Safety.AssertArgumentNotNull("request", request);

			command = Container.Resolve<GetProductFeedbackSummariesCommand>();
			return command.GetProductFeedbackSummaries(request);
		}

		#endregion // IProductFeedbackRuntimeService Members

	}

}
